#!/usr/bin/env python
# Copyright (c) 2014 Eugene Frolov <efrolov@mirantis.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import cgi
import cgitb
import os
import re
import sys
import tempfile

from rdb.old_app import config
from rdb.old_app import engine

cgitb.enable()


def HelloWorld():
    return "Hello World"


def About():
    return """author: <br />
    Evgenii Frolov (mail: profisphantom@gmail.com), <br />
    Perkova Irina (mail: iperkova@frigoglass.com).<br />
<br />
programming:<br />
    Evgenii Frolov (mail: profisphantom@gmail.com), <br />
    Johann Burkard (mail: jb@eaio.com),<br />
    Brandon Aaron,<br />
    Paul Bakaus (paulbakaus.com),<br />
    David Bolter,<br />
    Rich Caloggero,<br />
    Chi Cheng (cloudream@gmail.com),<br />
    Colin Clark (http://colin.atrc.utoronto.ca/),<br />
    Michelle D'Souza,<br />
    Aaron Eisenberger (aaronchi@gmail.com),<br />
    Ariel Flesler,<br />
    Bohdan Ganicky,<br />
    Scott González,<br />
    Marc Grabanski (m@marcgrabanski.com),<br />
    Klaus Hartl (stilbuero.de),<br />
    Scott Jehl,<br />
    Cody Lindley,<br />
    Eduardo Lundgren (eduardolundgren@gmail.com),<br />
    Todd Parker,<br />
    John Resig,<br />
    Patty Toland,<br />
    Ca-Phun Ung (yelotofu.com),<br />
    Keith Wood (kbwood@virginbroadband.com.au),<br />
    Maggie Costello Wachs,<br />
    Richard D. Worth (rdworth.org),<br />
    Jörn Zaefferer (bassistance.de).<br />
<br />
license: <br />
    GNU GPL2 (http://www.gnu.org/licenses/gpl-2.0.html)<br />
    <br />
    This program is free software; you can redistribute it and/or modify<br />
    it under the terms of the GNU General Public License as published by<br />
    the Free Software Foundation; either version 2 of the License, or<br />
(at your option) any later version.<br />
<br />
    This program is distributed in the hope that it will be useful,<br />
    but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
    GNU General Public License for more details.<br />
<br />
    You should have received a copy of the GNU General Public License<br />
    along with this program; if not, write to the Free Software<br />
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,<br />
    MA 02110-1301, USA."""


def CheckError():
    if Engine.ErrCode != 0:
        return Engine.msgByErrCode[Engine.ErrCode]
        sys.exit


def msplist():
    return Engine.GetXMLMSPTable()


def unitlist():
    return Engine.GetXMLUnitList()


def currencylist():
    return Engine.GetXMLCurrencyList()


def modellist():
    return Engine.GetXMLModelList()


def postmsp(code, description, description_rus, integer, model, planning_type,
            safety_stock, unit, planning_condition):
    postdate = {}
    postdate['code'] = code
    postdate['description'] = description
    postdate['description_rus'] = description_rus
    postdate['integer'] = integer
    postdate['model'] = list(model)
    postdate['planning_type'] = planning_type
    postdate['safety_stock'] = safety_stock
    postdate['unit'] = unit
    postdate['planning_condition'] = planning_condition
    return Engine.addMSPRecord(postdate)


def addUnit(name):
    return Engine.addUnit(name)


def addCurrency(name):
    return Engine.addCurrency(name)


def addModel(name):
    return Engine.addModel(name)


def test1():
    return Engine.test1()


def getMSPCSV():
    return Engine.GetCSV('MSP')


def ConvertPostToCSV(post):
    csvline = []
    csvfile = []
    post = post.replace('\r', '')
    post = post.replace("'", "\'")
    post = post.replace("`", "\'")
    for line in post.split('\n'):
        value = ""
        schar = ""
        for char in line:
            if ((char == config.csvSplitChar) and
                    (schar != config.csvStringChar)):
                csvline.append(value)
                value = ""
            else:
                if char == '"':
                    if schar == "":
                        schar = config.csvStringChar
                    else:
                        schar = ''
                else:
                    value += char
        csvline.append(value)
        value = ""
        csvfile.append(csvline)
        csvline = []
        if len(csvfile[-1]) < 2:
            del csvfile[-1]
    return csvfile


def setMSPCSV(filename):
    resCSV = ConvertPostToCSV(filename)
    if (len(resCSV) < 1) and (len(resCSV[0]) < 10):
        return "Error: Bad CSV file..."
    else:
        return Engine.setMSPCSV(resCSV)


def getMSPItem(id):
    return Engine.getMSPlineByID(id)


def getSizeDialog(userId, dialogName):
    return Engine.getSizeDialog(userId, dialogName)


def setDialogSize(userId, dialogName, left, top, width, height):
    return Engine.setDialogSize(userId, dialogName, left[:-2], top[:-2], width,
                                height)


def getMRTAI():
    return Engine.getMRTAI()


def spcode():
    return Engine.GetXMLSPCode()


def spcodetable(guid):
    return Engine.GetXMLSPCodeTable(guid)


def spcodetablefull(id):
    return Engine.GetXMLSPCodeTableFull(id)


def addSPCode(guid, spcode, quantity):
    return Engine.addSPCode(guid, spcode, quantity)


def delSPCodeByID(id):
    return Engine.delSPCodeByID(id)


def postmrt(repairType, autoRepairCodeInput, repairTypeRus, guid, model,
            repairTypePrice, repairPartsPrice, currency, customer):
    postdate = {}
    postdate['code'] = autoRepairCodeInput
    postdate['repairType'] = repairType
    postdate['repairTypeRus'] = repairTypeRus
    postdate['guid'] = guid
    postdate['model'] = model.split()
    postdate['repairTypePrice'] = repairTypePrice
    postdate['repairPartsPrice'] = repairPartsPrice
    postdate['currency'] = currency
    postdate['customer'] = customer
    return Engine.postmrt(postdate)


def getCustomerGroup():
    return Engine.getCustomerGroup()


def addCustomerGroup(group):
    return Engine.addCustomerGroup(group)


def addCustomer(name, group):
    return Engine.addCustomer(name, group)


def addDestination(daddr):
    return Engine.addDestination(daddr)


def getRepairType():
    return Engine.getRepairType()


def getRepairTypeFilter(customer, model):
    return Engine.getRepairTypeFilter(customer, model)


def getCustomer():
    return Engine.getCustomer()


def getDModel():
    return Engine.getDModel()


def getDDestination():
    return Engine.getDDestination()


def getTransactionType():
    return Engine.getTransactionType()


def addTransactionType(type, formula):
    return Engine.addTransactionType(type, formula)


def addInventoryAdjustment(spcode, transactiontype, quantity, date):
    return Engine.addInventoryAdjustment(spcode, transactiontype, quantity,
                                         date)


def getATI():
    return Engine.getATI()


def getTransactionByDate(fromdate, todate, fromitem, toitem, fromtype, totype):
    detail = "true"
    return Engine.getTransactionByDate(fromdate, todate, fromitem, toitem,
                                       fromtype, totype, detail)


def getTransactionByDateDetail(fromdate, todate, fromitem, toitem, fromtype,
                               totype, detail):
    return Engine.getTransactionByDate(fromdate, todate, fromitem, toitem,
                                       fromtype, totype, detail)


def getWarehouseInventoryByDate(date, zerro, safety):
    return Engine.getWarehouseInventoryByDate(date, zerro, safety)


def getWarehouseInventoryByItem(date, spcode):
    return Engine.getWarehouseInventoryByItem(date, spcode)


def getZeroQuantity():
    return Engine.getZeroQuantity()


def getReapairType():
    return Engine.getReapairType()


def setRepairNote(GUID, brand, ddate, dnote, rdate, rnumber, snote, snumber,
                  transactiontype):
    postdate = {}
    postdate['GUID'] = GUID
    postdate['brand'] = brand
    if ddate == "":
        postdate['ddate'] = 'NULL'
    else:
        postdate['ddate'] = ddate
    if dnote == "":
        postdate['dnote'] = 'NULL'
    else:
        postdate['dnote'] = '"' + dnote + '"'
    postdate['rdate'] = rdate
    postdate['rnumber'] = rnumber.upper()
    postdate['rtype'] = GUID
    if snote == "":
        postdate['snote'] = 'NULL'
    else:
        postdate['snote'] = '"' + snote + '"'
    postdate['cooler'] = snumber
    postdate['transactiontype'] = transactiontype
    return Engine.setRepairNote(postdate)


def getRepairNumber():
    return Engine.getRepairNumber()


def getConsumptionRepairCode():
    return Engine.getConsumptionRepairCode()


def getRepairNoteTable():
    return Engine.getRepairNoteTable()


def getRepairItem(id):
    return Engine.getRepairItem(id)


def getRepairNoteTableReport(param, value):
    return Engine.getRepairNoteTableReport(param, value)


def getGroupPricing():
    return Engine.getGroupPricing()


def getGroupPricingZero():
    return Engine.getGroupPricingZero()


def uploadPriceGroup(filename):
    csv = ConvertPostToCSV(filename)
    return Engine.UploadCSV(csv, 'gprice')


def getGPrices():
    return Engine.getGPrices()


def uploadCoolerInventory(filename):
    csv = ConvertPostToCSV(filename)
    return Engine.UploadCSV(csv, 'coolerinventory')


def getPrintDetailedInvoicebyPeriod(fromdate, todate, param):
    return Engine.getPrintDetailedInvoicebyPeriod(fromdate, todate, param)


def getPrintInvoicebyModel():
    return Engine.getPrintInvoicebyModel()


def getRNote():
    return Engine.getRNote()


def getPrintInvoicebyRepairType(rnote):
    return Engine.getPrintInvoicebyRepairType(rnote)


def getPrintOtherSparePartsperRepairNote(param):
    param = param.replace('&', '>')
    param = param.replace('&', '<')
    return Engine.getPrintOtherSparePartsperRepairNote(param)


def getPrintRepairNoteNumber(rnote):
    return Engine.getPrintRepairNoteNumber(rnote)


def getCoolerInventory(param):
    return Engine.getCoolerInventory(param)


def getSPNeedOrder():
    return Engine.getSPNeedOrder()


def addSPOrder(spcode, quantity, date):
    postdata = {}
    postdata['spcode'] = spcode
    postdata['quantity'] = quantity
    postdata['date'] = date
    return Engine.addSPOrder(postdata)


def uploadSPOrder(filename):
    csv = ConvertPostToCSV(filename.value)
    return Engine.UploadCSV(csv, 'sparepartsorder')


def getOrderedSPTable():
    return Engine.getOrderedSPTable()


def getCloseOrderedSPTable():
    return Engine.getCloseOrderedSPTable()


def CloseOrder(qty, id):
    return Engine.CloseOrder(qty, id)


def rtcodetable(guid):
    return Engine.GetXMLRTCodeTable(guid)


def addRTCode(guid, rtype):
    return Engine.addRTCode(guid, rtype)


def delRTCodeByID(id):
    return Engine.delRTCodeByID(id)


def uploadAdjustment(filename):
    csv = ConvertPostToCSV(filename)
    return Engine.UploadCSV(csv, 'inventoryadjustment')


def returnCooler(id):
    return Engine.returnCooler(id)


def getCoolerSNFromCoolerReceipt():
    return Engine.getCoolerSNFromCoolerReceipt()


def getCoolerById(id):
    return Engine.getCoolerById(id)


def getModelRepairCount(param):
    return Engine.getModelRepairCount(param)


def getXLSfile(htmldata):
    htmldata = htmldata.replace(u"\n", u"")
    htmldata = htmldata.replace(u'">', u"png\">\n")
    htmldata = re.sub(u'<img.*png\">', u'', htmldata)
    htmldata = htmldata.replace(u'.', u',')
    htmldata = htmldata.replace(u'Н,-Новгород', u'Н.-Новгород')
    unicname = os.path.basename(tempfile.mkstemp(prefix='report_')[1])
    unicname += '.xls'
    msg = (u"<html><head><meta http-equiv='Content-Type' content='text/html;"
           u"charset=utf-8' /></head><body><table>" + htmldata + u"</hable>"
           u"</body></html>")
    f = open(config.TMPDIR % unicname, 'w')
    f.write(msg.encode('utf8'))
    f.close()
    return "window.location.href = '/tmp/%s'" % unicname


def getMRTItem(id):
    return Engine.getMRTItem(id)


def getMySQLInfo():
    return Engine.getMySQLInfo()


funcOpt = {
    'HelloWorld': {'funcName': HelloWorld, 'format': 'HTML'},
    'About': {'funcName': About, 'format': 'HTML'},
    'CheckError': {'funcName': CheckError, 'format': 'HTML'},
    'msplist': {'funcName': msplist, 'format': 'XML'},
    'unitlist': {'funcName': unitlist, 'format': 'XML'},
    'currencylist': {'funcName': currencylist, 'format': 'XML'},
    'modellist': {'funcName': modellist, 'format': 'XML'},
    'postmsp': {'funcName': postmsp, 'param': [
        'code', 'description', 'description_rus', 'integer', 'model',
        'planning_type', 'safety_stock', 'unit',
        'planning_condition'], 'format': 'HTML'},
    'addUnit': {'funcName': addUnit, 'param': ['name'], 'format': 'HTML'},
    'addCurrency': {'funcName': addCurrency, 'param': ['name'],
                    'format': 'HTML'},
    'addModel': {'funcName': addModel, 'param': ['name'], 'format': 'HTML'},
    'test1': {'funcName': test1, 'format': 'HTML'},
    'getMSPCSV': {'funcName': getMSPCSV, 'format': 'HTML'},
    'ConvertPostToCSV': {'funcName': ConvertPostToCSV, 'param': ['post'],
                         'format': 'HTML'},
    'setMSPCSV': {'funcName': setMSPCSV, 'param': ['filename'],
                  'format': 'HTML'},
    'getMSPItem': {'funcName': getMSPItem, 'param': ['id'], 'format': 'HTML'},
    'getSizeDialog': {'funcName': getSizeDialog,
                      'param': ['userId', 'dialogName'], 'format': 'HTML'},
    'setDialogSize': {'funcName': setDialogSize,
                      'param': ['userId', 'dialogName',
                                'left', 'top',
                                'width', 'height'],
                      'format': 'HTML'},
    'getMRTAI': {'funcName': getMRTAI, 'format': 'HTML'},
    'spcode': {'funcName': spcode, 'format': 'XML'},
    'spcodetable': {'funcName': spcodetable, 'param': ['guid'],
                    'format': 'XML'},
    'spcodetablefull': {'funcName': spcodetablefull, 'param': ['id'],
                        'format': 'XML'},
    'addSPCode': {'funcName': addSPCode,
                  'param': ['guid', 'spcode', 'quantity'],
                  'format': 'HTML'},
    'delSPCodeByID': {'funcName': delSPCodeByID, 'param': ['id'],
                      'format': 'HTML'},
    'postmrt': {'funcName': postmrt,
                'param': ['repairType', 'autoRepairCodeInput', 'repairTypeRus',
                          'guid', 'model', 'repairTypePrice',
                          'repairPartsPrice', 'currency', 'customer'],
                'format': 'HTML'},
    'getCustomerGroup': {'funcName': getCustomerGroup, 'format': 'XML'},
    'addCustomerGroup': {'funcName': addCustomerGroup, 'param': ['group'],
                         'format': 'HTML'},
    'addCustomer': {'funcName': addCustomer, 'param': ['name', 'group'],
                    'format': 'HTML'},
    'addDestination': {'funcName': addDestination, 'param': ['daddr'],
                       'format': 'HTML'},
    'getRepairType': {'funcName': getRepairType, 'format': 'XML'},
    'getRepairTypeFilter': {'funcName': getRepairTypeFilter, 'format': 'XML',
                            'param': ['customer', 'model']},
    'getCustomer': {'funcName': getCustomer, 'format': 'XML'},
    'getDModel': {'funcName': getDModel, 'format': 'XML'},
    'getDDestination': {'funcName': getDDestination, 'format': 'XML'},
    'getTransactionType': {'funcName': getTransactionType, 'format': 'XML'},
    'addTransactionType': {'funcName': addTransactionType,
                           'param': ['type', 'formula'],
                           'format': 'HTML'},
    'addInventoryAdjustment': {'funcName': addInventoryAdjustment,
                               'param': ['spcode', 'transactiontype',
                                         'quantity', 'date'],
                               'format': 'HTML'},
    'getATI': {'funcName': getATI, 'format': 'HTML'},
    'getTransactionByDate': {'funcName': getTransactionByDate,
                             'param': ['fromdate', 'todate', 'fromitem',
                                       'toitem', 'fromtype', 'totype'],
                             'format': 'XML'},
    'getTransactionByDateDetail': {'funcName': getTransactionByDateDetail,
                                   'param': ['fromdate', 'todate', 'fromitem',
                                             'toitem', 'fromtype', 'totype',
                                             'detail'], 'format': 'XML'},
    'getWarehouseInventoryByDate': {'funcName': getWarehouseInventoryByDate,
                                    'param': ['date', 'zerro', 'safety'],
                                    'format': 'XML'},
    'getWarehouseInventoryByItem': {'funcName': getWarehouseInventoryByItem,
                                    'param': ['date', 'spcode'],
                                    'format': 'XML'},
    'getZeroQuantity': {'funcName': getZeroQuantity, 'format': 'XML'},
    'getReapairType': {'funcName': getReapairType, 'format': 'XML'},
    'setRepairNote': {'funcName': setRepairNote, 'param': [
        'GUID', 'brand', 'ddate', 'dnote', 'rdate', 'rnumber', 'snote',
        'snumber', 'transactiontype'], 'format': 'HTML'},
    'getRepairNumber': {'funcName': getRepairNumber, 'format': 'HTML'},
    'getConsumptionRepairCode': {'funcName': getConsumptionRepairCode,
                                 'format': 'HTML'},
    'getRepairNoteTable': {'funcName': getRepairNoteTable, 'format': 'XML'},
    'getRepairItem': {'funcName': getRepairItem, 'param': ['id'],
                      'format': 'HTML'},
    'getRepairNoteTableReport': {'funcName': getRepairNoteTableReport,
                                 'param': ['param', 'value'], 'format': 'XML'},
    'getGroupPricing': {'funcName': getGroupPricing, 'format': 'CSV'},
    'getGroupPricingZero': {'funcName': getGroupPricingZero, 'format': 'CSV'},
    'uploadPriceGroup': {'funcName': uploadPriceGroup, 'param': ['filename'],
                         'format': 'HTML'},
    'getGPrices': {'funcName': getGPrices, 'format': 'XML'},
    'uploadCoolerInventory': {'funcName': uploadCoolerInventory,
                              'param': ['filename'], 'format': 'HTML'},
    'getPrintDetailedInvoicebyPeriod': {
        'funcName': getPrintDetailedInvoicebyPeriod,
        'param': ['fromdate', 'todate', 'param'], 'format': 'XML'},
    'getPrintInvoicebyModel': {'funcName': getPrintInvoicebyModel,
                               'format': 'XML'},
    'getRNote': {'funcName': getRNote, 'format': 'XML'},
    'getPrintInvoicebyRepairType': {'funcName': getPrintInvoicebyRepairType,
                                    'param': ['rnote'], 'format': 'XML'},
    'getPrintOtherSparePartsperRepairNote': {
        'funcName': getPrintOtherSparePartsperRepairNote,
        'param': ['param'], 'format': 'XML'},
    'getPrintRepairNoteNumber': {'funcName': getPrintRepairNoteNumber,
                                 'param': ['rnote'], 'format': 'XML'},
    'getCoolerInventory': {'funcName': getCoolerInventory, 'param': ['param'],
                           'format': 'XML'},
    'getSPNeedOrder': {'funcName': getSPNeedOrder, 'format': 'XML'},
    'addSPOrder': {'funcName': addSPOrder, 'param': ['spcode', 'quantity',
                   'date'], 'format': 'HTML'},
    'uploadSPOrder': {'funcName': uploadSPOrder, 'param': ['filename'],
                      'format': 'HTML'},
    'getOrderedSPTable': {'funcName': getOrderedSPTable, 'format': 'XML'},
    'getCloseOrderedSPTable': {'funcName': getCloseOrderedSPTable,
                               'format': 'XML'},
    'CloseOrder': {'funcName': CloseOrder, 'param': ['qty', 'id'],
                   'format': 'HTML'},
    'rtcodetable': {'funcName': rtcodetable, 'param': ['guid'],
                    'format': 'XML'},
    'addRTCode': {'funcName': addRTCode, 'param': ['guid', 'rtype'],
                  'format': 'HTML'},
    'delRTCodeByID': {'funcName': delRTCodeByID, 'param': ['id'],
                      'format': 'HTML'},
    'uploadAdjustment': {'funcName': uploadAdjustment, 'param': ['filename'],
                         'format': 'HTML'},
    'returnCooler': {'funcName': returnCooler, 'param': ['id'],
                     'format': 'HTML'},
    'getCoolerSNFromCoolerReceipt': {'funcName': getCoolerSNFromCoolerReceipt,
                                     'format': 'XML'},
    'getCoolerById': {'funcName': getCoolerById, 'param': ['id'],
                      'format': 'HTML'},
    'getModelRepairCount': {'funcName': getModelRepairCount,
                            'param': ['param'],
                            'format': 'XML'},
    'getXLSfile': {'funcName': getXLSfile, 'param': ['htmldata'],
                   'format': 'HTML'},
    'getMRTItem': {'funcName': getMRTItem, 'param': ['id'], 'format': 'HTML'},
    'getMySQLInfo': {'funcName': getMySQLInfo, 'format': 'HTML'}
}

Engine = engine.engine()
Engine.ErrCode = 0
if Engine.ConnectToBD() is None:
    Engine.ErrCode = 1

# vars = cgi.FieldStorage()

# hhider = funcOpt[vars['func'].value]['format']

# if hhider == "HTML":
#     print "Content-type: text/html"
#     print
# elif hhider == "XML":
#     print "Content-type: text/xml"
#     print
# elif hhider == "CSV":
#     print "Content-type: text/csv"
#     print

# evStr = "funcOpt[vars['func'].value]['funcName'](\"%s\")"
# try:
#     n = len(funcOpt[vars['func'].value]['param'])
# except KeyError:
#     n = 0
# if vars['func'].value == 'getXLSfile':
#     tmpstr = vars['htmldata'].value
#     print vars.keys()
#     print funcOpt['getXLSfile']['funcName'](tmpstr)
# elif vars['func'].value == 'uploadCoolerInventory':
#     print uploadCoolerInventory(vars['filename'].file.read())
# elif vars['func'].value == 'setMSPCSV':
#     print setMSPCSV(vars['filename'].file.read())
# elif vars['func'].value == 'uploadPriceGroup':
#     print uploadPriceGroup(vars['filename'].file.read())
# elif vars['func'].value == 'uploadAdjustment':
#     print uploadAdjustment(vars['filename'].file.read())
# elif n == 0:
#     print funcOpt[vars['func'].value]['funcName']()
# elif n == 1:
#     try:
#         evStr = evStr % (
#             str(vars[funcOpt[vars['func'].value]['param'][0]].value))
#     except KeyError:
#         evStr = evStr % ("")
#     print eval(evStr)
# else:
#     for i in xrange(n - 1):
#         try:
#             evStr = evStr % (
#                 str(
#                     vars[funcOpt[vars['func'].value]['param'][i]].value
#                 ).replace("\n", "") + "\", \"%s")
#         except AttributeError:
#             x = vars[funcOpt[vars['func'].value]['param'][i]]
#             rr = ""
#             if type(x) == list:
#                 for jj in x:
#                     rr += str(jj.value) + " "
#                 rr = rr[:-1]
#                 evStr = evStr % (rr + '", "%s')
#             else:
#                 raise
#         except KeyError:
#             evStr = evStr % ('' + "\", \"%s")
#         except TypeError:
#             print (vars[funcOpt[vars['func'].value]['param'][i]].value,
#                    funcOpt[vars['func'].value]['param'][i], i)
#     try:
#         evStr = evStr % (str(vars[funcOpt[vars['func'].value][
#             'param'][n - 1]].value).replace("\n", ""))
#     except KeyError:
#         evStr = evStr % ('')
#     except TypeError:
#             print (vars[funcOpt[vars['func'].value]['param'][n - 1]].value,
#                    funcOpt[vars['func'].value]['param'][n - 1], n - 1)
#     print eval(evStr)
